#pragma once

#include "dfa.hpp"

namespace dfa
{
    class DfaGroup
    {
    public:
        static DfaGroup* createDfaGroup()
        { return new DfaGroup(); }

        void add(Dfa* dfa)
        { _dfa_group.push_back(dfa); }

        void toRemove(Dfa* dfa)
        { _dfa_to_remove.push_back(dfa); }

        void commitRemove()
        {
            for (auto& e : _dfa_to_remove) {
                auto it = find(_dfa_group.begin(), _dfa_group.end(), e);
                _dfa_group.erase(it);
            }
            _dfa_to_remove.clear();
        }

        bool contain(Dfa* dfa)
        { return find(_dfa_group.cbegin(), _dfa_group.cend(), dfa) != _dfa_group.cend(); }

        std::vector<Dfa*>& getGroup() 
        { return _dfa_group; } 

        Dfa* getDfaAt(uint32_t index)
        { return index < _dfa_group.size() ? _dfa_group[index] : nullptr; }

        auto getGroupNum()
        { return _group_num; }

    private:
        // bool operator==(const DfaGroup& other) const
        // { return _group_num == other._group_num; }

        DfaGroup() : _group_num(DfaGroup::GROUP_COUNT++) {};

        virtual ~DfaGroup() {};

        static size_t GROUP_COUNT; 
        uint32_t _group_num;
        std::vector<Dfa*> _dfa_group;
        std::vector<Dfa*> _dfa_to_remove;
    };

    size_t DfaGroup::GROUP_COUNT = 0;
} /* namespace dfa */
